#ifndef SCRIPT_MODULE_H
#define SCRIPT_MODULE_H

#include "config.h"
#include <stdint.h>
#include <cstdint>
#include <cstring>

/**
 * 脚本模块使用动态库加载的形式，所以需要实现一些固定的函数
 */

class IScript;

struct ScriptBuildInfo {
    const char *title;      // title of this script
    const char *file_path;  // source file path
    const char *usage;      // usage hint
    const char *usage_extra;// addition info for usage
    const char *code;       // code of the script

    [[nodiscard]] inline bool Valid() const {
        return 
            (title && strlen(title) > 0) &&
            (file_path && strlen(file_path) > 0) &&
            (usage && strlen(usage) > 0) &&
            (usage_extra && strlen(usage_extra) > 0) &&
            (code && strlen(code) > 0);
    }
};

using ScriptBuilder = IScript *(*)(const ScriptBuildInfo *);
using ModuleInitProc = bool(*)();
using ModuleCleanupPorc = void(*)();

struct ScriptModuleInfo
{
    const int32_t     support_hot_reload; // 模块脚本是否支持热重载
    const char       *name; // 模块名称
    const char       *desc; // 模块描述
    const char       *lang; // 模块使用的语言
    ModuleInitProc    init; // 模块初始化
    ModuleCleanupPorc cleanup;   // 即将退出，清理模块
    ScriptBuilder     build_script; // 创建脚本扩展对象
};

#define MODULE_ENTRY_NAME "GetModuleInfo"
using ModuleEntryFunc = const ScriptModuleInfo* (*)(void);

#define IMPL_MODULE_ENTRY() \
extern "C" SYMBOL_EXPORT const ScriptModuleInfo *GetModuleInfo(void)

extern const ScriptModuleInfo *g_current_module; // IMPLEMENT BY MODULE SELF

#endif /* SCRIPT_MODULE_H */
